package com.boot.down.util;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;

/**
 * @author dell
 */
public class Message {

    private static final long serialVersionUID = -4550277881300593979L;
    /**
     * 操作是否成功，默认为成功
     */
    private boolean success = true;

    /**
     * 方法调用过程中产生的返回消息集合
     * 如果处理失败<code>success</code>为false，则最后一条表示失败的具体消息
     */
    private List<String> messages;

    /**
     * 函数调用过程中需要传递的参数
     */
    private Map<String, Object> paramMap;

    /**
     * 构建一个消息对象
     * @return 消息对象
     */
    public static Message build() {
        return new Message();
    }

    /**
     * 构建消息对象
     * @param success 操作是否成功
     * @return 消息对象
     */
    public static Message build(boolean success) {
        return new Message(success);
    }

    /**
     * 构建消息对象
     * @param result 是否成功，大于0表示操作成功
     * @param successMsg 成功的返回消息
     * @param failMsg 失败的返回消息
     * @return 消息对象
     */
    public static Message build(int result, String successMsg, String failMsg) {
        return build(result > 0, successMsg, failMsg);
    }

    /**
     * 构建一个消息对象
     * @param success 是否成功
     * @param successMsg 成功的返回消息
     * @param failMsg 失败的返回消息
     * @return 消息对象
     */
    public static Message build(boolean success, String successMsg, String failMsg) {
        Message message = new Message(success);
        if (success) {
            message.setMessage(successMsg);
        } else {
            message.setMessage(failMsg);
        }

        return message;
    }

    /**
     * 构建返回消息，<code>result</code>大于0表示true
     * @param result 操作结果，大于0表示true
     * @return 消息对象
     */
    public static Message build(int result) {
        return new Message(result > 0);
    }

    /**
     * 构建一个消息对象
     * @param success 是否成功
     * @param msg 返回消息
     * @return 消息对象
     */
    public static Message build(boolean success, String msg) {
        return new Message(success, msg);
    }

    /**
     * 构建一个消息对象
     * @param message 传播的消息对象
     * @return 消息对象
     */
    public static Message build(Message message) {
        return new Message(message);
    }

    private Message() {
        messages = Lists.newArrayList();
        paramMap = Maps.newHashMap();
        setDefaultMessage();
    }

    private Message(boolean success) {
        messages = Lists.newArrayList();
        paramMap = Maps.newHashMap();
        this.success = success;
        setDefaultMessage();
    }

    private void setDefaultMessage() {
        if (success) {
            messages.add("请求处理完成");
        } else {
            messages.add("操作失败");
        }
    }

    private Message(boolean success, String content) {
        this.messages = Lists.newArrayList();
        paramMap = Maps.newHashMap();

        if (StringUtils.isNotBlank(content)) {
            this.messages.add(content);
        } else {
            setDefaultMessage();
        }
        this.success = success;
    }

    private Message(Message message) {
        messages = Lists.newArrayList();
        paramMap = Maps.newHashMap();
        append(message);
    }


    public Message append(Message message) {
        if (null != message) {
            // 操作失败后，需要一直保存下去
            if (!message.isSuccess()) {
                this.success = message.isSuccess();
                //操作失败时才接收信息
                messages.addAll(message.messages);
            }
            paramMap.putAll(message.getParamMap());
        }
        return this;
    }

    public boolean isSuccess() {
        return success;
    }

    public Message setSuccess(boolean success) {
        if (this.success) {
            this.success = success;
        }
        return this;
    }

    public List<String> getMessages() {
        return messages;
    }

    public String getLashMessaage() {
        return messages.get(messages.size() - 1);
    }

    public Message setMessage(String message) {
        this.messages.add(message);
        return this;
    }

    /**
     * 消息传递过程中添加参数
     * @param key   参数的键值
     * @param value 键值对应的值
     */
    public Message addParam(String key, Object value) {
        paramMap.put(key, value);
        return this;
    }

    /**
     * 获取消息传递的参数信息
     * @return 参数MAP
     */
    public Map<String, Object> getParamMap() {
        return paramMap;
    }

    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();
        result.append("操作结果：[").append(success).append("],");
        result.append("返回消息：[");
        for (String content : messages) {
            result.append(content).append(" ");
        }
        result.append("]");
        return result.toString();
    }

}
